Some computer programs are organized into multiple threads, which can be run simultaneously on different processors and/or can be multiplexed on a single processor. During execution, a thread may try to acquire a resource, such as an object in memory or a particular piece of hardware, which one or more other threads are also trying to acquire or have already acquired. Resources may be shared between threads due to memory, cost, and/or other constraints, for example. Shared resources may also be used to synchronize threads with one another and/or with system operations such as “garbage collection” which reclaims unused memory, for example. When more threads attempt to access a resource than the resource is designed to allow, the threads are said to “contend” with one another for the resource.